from django.shortcuts import render,redirect
from django.urls import reverse #导入反项解析
from django.views import View
from django import http
import re
from django.contrib.auth import login,authenticate  # 导入实现状态保持的函数

# 导入数据库异常
from django.db import DatabaseError
from django_redis import get_redis_connection
from users.models import User
# 前面有报错，所以没有提示
from meiduo_shopp.utils.response_code import RETCODE


# 用户登录
class LoginView(View):
    # 登录页面
    def get(self,request):
        return render(request,"login.html")

    # 获取登录信息，实现业务逻辑
    def post(self,request):
        """实现登录逻辑"""
        # 接收参数
        username = request.POST.get('username')
        password = request.POST.get('password')
        remembered = request.POST.get('remembered')
        # 校验参数
        # 非空校验
        if not all([username,password]):
            return http.HttpResponseForbidden("缺少必传参数")
        if not re.match(r"^[a-zA-Z0-9-_]{5,20}$",username):
            return http.HttpResponseForbidden("请输入正确的用户名或者手机号")
        if not re.match(r"^[a-zA-Z0-9]{8,20}$",password):
            return http.HttpResponseForbidden("密码最少8位，最长20位")
        # 认证用户
        # user = User.objects.filter(username=username).first()
        user = authenticate(username=username,password=password)
        if user is None:
            return render(request,"login.html",{"account_errmsg":"账号密码错误"})
        # 状态保持
        login(request,user)
        # 使用remembered确定状态保持周期，实现记住登录状态
        if remembered != "on":
           #就是没有记录状态，在浏览器上回话结束就销毁
            request.session.set_expiry(0)  # 单位为秒
        else:
            request.session.set_expiry(None)  # 默认为两周。
        # 响应结果
        return redirect(reverse("contents:index"))




class UsernameCountView(View):
    # 判断用户名是否重复
    def get(self,request,username):
        """
        :param username:用户名
        :return: 返回JSON字符串
        """
        # 接收参数和校验参数，在路由配置中已经做了，不需要重复做了
        # 实现主体业务逻辑：使用username查询对应的记录数(filter返回满足条件的结果集)
        count = User.objects.filter(username=username).count()
        # 响应结果
        return http.JsonResponse({"code": RETCODE.OK, "errmsg": "OK", "count": count})

# 判断手机号是否重复
class Mobile(View):
    def get(self,request,mobile):
        phon = User.objects.filter(mobile=mobile).count()
        return http.JsonResponse({"code":RETCODE.OK,"errmsg":'OK',"count":phon})


class RegisterView(View):
    """用户注册视图"""
    def get(self,request):
        """提供展示用户注册页面的效果"""
        return render(request,"register.html")

#   实现注册业务逻辑
    def post(self,request):
        # 1.接收参数
        username = request.POST.get('username')
        password = request.POST.get('password')
        password2 = request.POST.get("password2")
        mobile = request.POST.get("mobile")
        allow = request.POST.get("allow")
        sms_code_client = request.POST.get("sms_code")
        print("username=", username, ",password=", password, ",password2=", password2,
              ",mobile=" + mobile + ",allow=" + allow)
        # 2.效验参数
        # 判断是否为空
        if not all([username,password,password2,mobile,allow]):
            return http.HttpResponseForbidden('缺少必传的参数')
        # 判断用户名是否合格
        if not re.match(r"^[a-zA-Z0-9_-]{5,20}$", username):
            return http.HttpResponseForbidden("请输入5-20个字符的用户名")
        # 判断密码是否符合
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.HttpResponseForbidden('请输入8-20位的密码')
        # 判断两次密码是否一致
        if password != password2:
            return http.HttpResponseForbidden('两次输入的密码不一致')
        # 判断手机号是否合法
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseForbidden('请输入正确的手机号码')
        # 判断短信验证码是否正确
        redis_conn = get_redis_connection("verify_code")
        sms_code_server = redis_conn.get("sms_%s"%mobile)
        if sms_code_server is None:
            return render(request, "register.html", {"sms_code_errmsg": "短信验证码已失效"})
        if sms_code_client != sms_code_server.decode():
            return render(request, "register.html", {"sms_code_errmsg": "输入短信验证码错误"})
        # 判断是否勾选用户协议
        if allow != 'on':
            return http.HttpResponseForbidden('请勾选用户协议')
        # 3.执行业务逻辑：保存注册数据，是注册业务的核心
        try:
            user = User.objects.create_user(username, password=password, mobile=mobile)
        except DatabaseError:
            return render(request, "register.html", {"register_err_msg": "注册失败"})

        # 实现状态保持
        login(request, user)


        # 4. 响应结果：重定向到首页
        # return redirect('/')  #重定向到首页  不通用
        return redirect(reverse('contents:index'))  #反项解析，通用


